package com.yoso.shop.application.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.NumberUtil;
import com.alibaba.fastjson.JSON;
import com.yoso.api.info.log.StockLogInfo;
import com.yoso.base.infrastructure.exception.BaseException;
import com.yoso.base.infrastructure.factory.BeanFactory;
import com.yoso.base.service.BaseService;
import com.yoso.shop.application.service.IStockService;
import com.yoso.shop.domain.stock.StockEntity;
import com.yoso.shop.domain.stock.StockEntityExample;
import com.yoso.shop.infrastructure.utils.RabbitMqUtils;
import com.yoso.shop.interfaces.vo.stock.StockVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Map;

/**
 * @author shizejin
 * @date 2022/1/30
 * @description:
 */
@Service
@Slf4j
public class StockServiceImpl extends BaseService<StockEntity, StockVo, StockEntityExample> implements IStockService {
    @Autowired
    private RabbitMqUtils mqUtils;

    @Override
    public StockEntity V2E(StockVo data) {
        return JSON.parseObject(JSON.toJSONString(data), StockEntity.class);
    }

    @Override
    public StockVo E2V(StockEntity data) {
        return JSON.parseObject(JSON.toJSONString(data), StockVo.class);

    }

    @Override
    public StockEntityExample getEntityExample(Map<String, String> paramMap) {
        StockEntityExample example = new StockEntityExample();
        example.createCriteria()
                .andColorIsNotNull()
                .andSizeIsNotNull();
        return example;
    }

    @Override
    public synchronized void reduceStock(StockVo stockVo, String source, String remark) {
        StockVo hisStockVo = this.findByUniqueKey(stockVo);
        log.info("历史库存记录：{}", JSON.toJSONString(hisStockVo));
        if (ObjectUtils.isEmpty(hisStockVo)) {
            String errMsg = String.format("未找到该库存记录！（商品代码：%s,颜色：%s,大小：%s）", stockVo.getCode(), stockVo.getColor(), stockVo.getSize());
            throw new RuntimeException(errMsg);
        }
        String sub = NumberUtil.sub(hisStockVo.getNumber(), stockVo.getNumber()).toString();
        hisStockVo.setNumber(Integer.valueOf(sub));
        this.updateRecord(hisStockVo);
        log.info("当前库存记录：{}", JSON.toJSONString(hisStockVo));
//        通知写入日志
        buildStockLogInfoAndSendMsg(stockVo, source, remark);
    }

    @Override
    public StockVo findByUniqueKey(StockVo stockVo) {
        String code = stockVo.getCode();
        String size = stockVo.getSize();
        String color = stockVo.getColor();
        if (StringUtils.isAnyBlank(code, size, color)) {
            return null;
        }
        StockEntityExample example = new StockEntityExample();

        example.createCriteria()
                .andCodeEqualTo(code)
                .andSizeEqualTo(size)
                .andColorEqualTo(color);
        List<StockVo> list = this.selectByExample(example);
        if (CollUtil.isEmpty(list)) {
            return null;
        }
        return list.get(0);
    }

    @Override
    @Transactional(rollbackFor = BaseException.class)
    public synchronized void addStock(StockVo stockVo, String source, String remark) {
        StockVo hisStockVo = this.findByUniqueKey(stockVo);
        log.info("历史库存记录：{}", JSON.toJSONString(hisStockVo));
        if (ObjectUtils.isNotEmpty(hisStockVo)) {
            String add = NumberUtil.add(hisStockVo.getNumber(), stockVo.getNumber()).toString();
            hisStockVo.setNumber(Integer.valueOf(add));
            this.insertSelective(hisStockVo);
            log.info("当前库存记录：{}", JSON.toJSONString(hisStockVo));
        } else {
            this.insertSelective(stockVo);
            log.info("当前库存记录：{}", JSON.toJSONString(stockVo));
        }
//        通知写入日志
        buildStockLogInfoAndSendMsg(stockVo, source, remark);
    }

    /**
     * 获得未维护库存的商品
     */
    @Override
    public List<StockVo> getUnSafeguardStock() {
        StockEntityExample example = new StockEntityExample();
        example.createCriteria()
                .andColorIsNull()
                .andSizeIsNull();
        return this.selectByExample(example);
    }

    private void buildStockLogInfoAndSendMsg(StockVo stockVo, String source, String remark) {
        StockLogInfo stockLogInfo = BeanFactory.convertBean(stockVo, StockLogInfo.class);
        stockLogInfo.setRemark(remark);
        stockLogInfo.setSource(source);
        sendStockInfoMsg(stockLogInfo);
    }

    private void sendStockInfoMsg(StockLogInfo stockLogInfo) {
        stockLogInfo.setUpdateTime(DateUtil.now());
        log.info("通知更新库存日志:{}", JSON.toJSONString(stockLogInfo));
        mqUtils.flushStockInfo(stockLogInfo);
    }
}
